package com.ruge.sms.service.impl;

import com.ruge.core.enums.SmsEnum;
import com.ruge.core.response.Response;
import com.ruge.core.tool.AssertTool;
import com.ruge.core.tool.RedisKeyTool;
import com.ruge.sms.error.SmsError;
import com.ruge.sms.service.SmsService;
import com.ruge.tool.str.StringTool;
import com.tencentcloudapi.common.Credential;
import com.tencentcloudapi.sms.v20210111.SmsClient;
import com.tencentcloudapi.sms.v20210111.models.SendSmsRequest;
import com.tencentcloudapi.sms.v20210111.models.SendSmsResponse;
import lombok.SneakyThrows;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * @program: ruge-cloud
 * @description:
 * @author: ruge.wu
 * @create: 2022-01-09 00:18
 **/
@Service
public class SmsServiceImpl implements SmsService {


    @Value("${tencent.cos.secret-id}")
    private String secretId;
    @Value("${tencent.cos.secret-key}")
    private String secretKey;
    @Value("${tencent.cos.bucket-name}")
    private String bucketName;
    @Value("${tencent.cos.region-id}")
    private String regionId;
    @Value("${tencent.cos.base-url}")
    private String baseUrl;
    @Value("${tencent.sms.appId}")
    private String smsAppId;

    @Resource
    private RedisTemplate<String, String> redisTemplate;

    /**
     * @param smsEnum {@link SmsEnum}
     * @param mobiles 手机号
     * @param params  短信参数
     * @return {@link Response}
     * @author ruge.wu
     */
    @Override
    @SneakyThrows
    public Response sendSms(SmsEnum smsEnum, List<String> mobiles, String[] params) {
        String smsKey = RedisKeyTool.buildSmsKey(smsEnum, mobiles.get(0));
        String value = redisTemplate.opsForValue().get(smsKey);
        if (StringTool.isNotBlank(value) && smsEnum.getStoreDb()) {
            return Response.create(SmsError.SMS_HAS_SEND, value);
        }
        Credential cred = new Credential(secretId, secretKey);
        SmsClient smsClient = new SmsClient(cred, regionId);
        SendSmsRequest req = new SendSmsRequest();
        req.setPhoneNumberSet(mobiles.toArray(new String[0]));
        req.setTemplateId(smsEnum.getValue());
        req.setSignName(smsEnum.getSign());
        req.setSmsSdkAppId(smsAppId);
        req.setTemplateParamSet(params);
        // 调用短信服务发送短信
        SendSmsResponse sendSmsResponse = smsClient.SendSms(req);
        if (smsEnum.getStoreDb()) {
            // 发送成功，将 code 保存至 Redis，失效时间 60s
            redisTemplate.opsForValue().set(smsKey, params[0], 60, TimeUnit.SECONDS);
        }
        return Response.create(sendSmsResponse);
    }

    /**
     * 验证码校验
     *
     * @param smsEnum {@link SmsEnum}
     * @param mobiles 手机号
     * @param params  短信参数
     * @return {@link Response}
     * @author ruge.wu
     */
    @Override
    public Response validSms(SmsEnum smsEnum, List<String> mobiles, String[] params) {
        String smsKey = RedisKeyTool.buildSmsKey(smsEnum, mobiles.get(0));
        String value = redisTemplate.opsForValue().get(smsKey);
        String param = params[0];

        AssertTool.mustTrue(value.equals(param), SmsError.CODE_VALID_FAILED);
        redisTemplate.delete(smsKey);
        return Response.create();
    }
}
